#!/usr/bin/python
#coding:utf-8

import re
import json
import MySQLdb
import sys


reload(sys)
sys.setdefaultencoding("utf-8")

sql_host = '192.168.1.218'
sql_user = 'root'
sql_passwd = 'mysql'
sql_db = 'mtrops'


def mysql_con(host, user, passwd, db, sql):
    # 打开数据库连接
    db = MySQLdb.connect(host, user, passwd, db, charset='utf8')
    # 使用cursor()方法获取操作游标
    cursor = db.cursor()
    # 使用execute方法执行SQL语句
    cursor.execute(sql)
    # 使用 fetchone() 方法获取一条数据
    data = cursor.fetchall()

    db.commit()
    # 关闭数据库连接
    db.close()
    return data


def remove_obstruct_char(cmd_str):
    '''删除一些干扰的特殊符号'''
    control_char = re.compile(r'\x07 | \x1b\[1P | \r ', re.X)
    cmd_str = control_char.sub('', cmd_str.strip())
    patch_char = re.compile('\x08\x1b\[C')  # 删除方向左右一起的按键
    while patch_char.search(cmd_str):
        cmd_str = patch_char.sub('', cmd_str.rstrip())
    return cmd_str


def deal_backspace(match_str, result_command, pattern_str, backspace_num):
    '''
    处理删除确认键
    '''
    if backspace_num > 0:
        if backspace_num > len(result_command):
            result_command += pattern_str
            result_command = result_command[0:-backspace_num]
        else:
            result_command = result_command[0:-backspace_num]
            result_command += pattern_str
    del_len = len(match_str) - 3
    if del_len > 0:
        result_command = result_command[0:-del_len]
    return result_command, len(match_str)



def deal_replace_char(match_str, result_command, backspace_num):
    '''
    处理替换命令
    '''
    str_lists = re.findall(r'(?<=\x1b\[1@)\w', match_str)
    tmp_str = ''.join(str_lists)
    result_command_list = list(result_command)
    if len(tmp_str) > 1:
        result_command_list[-backspace_num:-(backspace_num - len(tmp_str))] = tmp_str
    elif len(tmp_str) > 0:
        if result_command_list[-backspace_num] == ' ':
            result_command_list.insert(-backspace_num, tmp_str)
        else:
            result_command_list[-backspace_num] = tmp_str
    result_command = ''.join(result_command_list)
    return result_command, len(match_str)


def remove_control_char(result_command):
    """
    处理日志特殊字符
    """
    control_char = re.compile(r"""
                \x1b[ #%()*+\-.\/]. |
                \r |                                               #匹配 回车符(CR)
                (?:\x1b\[|\x9b) [ -?]* [@-~] |                     #匹配 控制顺序描述符(CSI)... Cmd
                (?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 |   #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL)
                (?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST)
                \x1b.                                              #匹配 转义过后的字符
                [\x80-\x9f] | (?:\x1b\]0;.*@.*:~)  | (.*mysql>.*) #匹配 所有控制字符
                """, re.X)
    result_command = control_char.sub('', result_command.strip())


    if result_command.startswith('vi') or result_command.startswith('fg'):
        vim_flag = True
    return result_command.decode('utf8', "ignore")


def deal_command(str_r):
    """
        处理命令中特殊字符
    """
    str_r = remove_obstruct_char(str_r)

    result_command = ''  # 最后的结果
    backspace_num = 0  # 光标移动的个数
    reach_backspace_flag = False  # 没有检测到光标键则为true
    pattern_str = ''
    while str_r:
        tmp = re.match(r'\s*\w+\s*', str_r)
        if tmp:
            str_r = str_r[len(str(tmp.group(0))):]
            if reach_backspace_flag:
                pattern_str += str(tmp.group(0))
                continue
            else:
                result_command += str(tmp.group(0))
                continue

        tmp = re.match(r'\x1b\[K[\x08]*', str_r)
        if tmp:
            result_command, del_len = deal_backspace(str(tmp.group(0)), result_command, pattern_str, backspace_num)
            reach_backspace_flag = False
            backspace_num = 0
            pattern_str = ''
            str_r = str_r[del_len:]
            continue

        tmp = re.match(r'\x08+', str_r)
        if tmp:
            str_r = str_r[len(str(tmp.group(0))):]
            if len(str_r) != 0:
                if reach_backspace_flag:
                    result_command = result_command[0:-backspace_num] + pattern_str
                    pattern_str = ''
                else:
                    reach_backspace_flag = True
                backspace_num = len(str(tmp.group(0)))
                continue
            else:
                break

        tmp = re.match(r'(\x1b\[1@\w)+', str_r)  # 处理替换的命令
        if tmp:
            result_command, del_len = deal_replace_char(str(tmp.group(0)), result_command, backspace_num)
            str_r = str_r[del_len:]
            backspace_num = 0
            continue

        if reach_backspace_flag:
            pattern_str += str_r[0]
        else:
            result_command += str_r[0]
        str_r = str_r[1:]

    if backspace_num > 0:
        result_command = result_command[0:-backspace_num] + pattern_str

    result_command = remove_control_char(result_command)
    return result_command


def main(ip,user,time_str,log):
    a = log
    try:
        b =  json.loads(a)
    except:
        b = a
    c= "".join(b)
    d =  deal_command(c)

    e = re.sub(r"]# \[",']# \n[',d)

    log = re.sub(r"\x1b\]0;.*@.*:.*\[", "[", e)

    sql_select_hostname = "select msg from app_cmdb_hostinfo where ip='%s'" % ip
    hostname = mysql_con(sql_host, sql_user, sql_passwd, sql_db, sql_select_hostname)[0][0]
    sql_insert = "INSERT INTO app_log_audit(hostname,host_ip,user_name,start_time,audit_log) VALUES('%s','%s','%s','%s','%s')" % (
        hostname, ip, user, time_str,log)
    mysql_con(sql_host, sql_user, sql_passwd, sql_db, sql_insert)